﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UIShell.OSGi;
using UIShell.OSGi.Core.Service;
using UIShell.OSGi.Loader;

namespace UIShell.OSGI.Mvc
{
    public static class BundleRuntimeExtensions
    {
        private static readonly HashSet<string> AssemblyNames = new HashSet<string>();
        public static void InvokeAddReferencedAssembly(this BundleRuntime runtime, Action<Assembly> addReferencedAssembly)
        {
            foreach (var bundle in runtime.Framework.Bundles)
            {
                var bundleData = runtime.GetFirstOrDefaultService<IBundleInstallerService>()
                                 .GetBundleDataByName(bundle.SymbolicName);
                if (bundleData == null) continue;

                var serviceContainer = runtime.Framework.ServiceContainer;
                var service = serviceContainer.GetFirstOrDefaultService<IRuntimeService>();
                var assemblies = service.LoadBundleAssembly(bundle.SymbolicName);
                assemblies.ForEach(assembly => TryAddReferencedAssembly(assembly, addReferencedAssembly));
                //foreach (var assemlby in assemlbies)
                //{
                //    var runtimeFolder = new DirectoryInfo(
                //        Path.Combine(AppDomain.CurrentDomain.DynamicDirectory, bundle.SymbolicName));
                //    if (!Directory.Exists(runtimeFolder.FullName))
                //        Directory.CreateDirectory(runtimeFolder.FullName);

                //    var assemlbyFile = new FileInfo(assemlby.Location);
                //    var shadowCopiedPlug = new FileInfo(
                //        Path.Combine(runtimeFolder.FullName, assemlbyFile.Name));

                //    File.Copy(assemlby.Location, shadowCopiedPlug.FullName, true);
                //    addReferencedAssembly(
                //        Assembly.Load(AssemblyName.GetAssemblyName(shadowCopiedPlug.FullName)));
                //}
            }
        }

        private static void TryAddReferencedAssembly(Assembly assembly, Action<Assembly> addReferencedAssembly)
        {
            if (AssemblyNames.Contains(assembly.FullName)) return;

            addReferencedAssembly(assembly);
            AssemblyNames.Add(assembly.FullName);
        }
    }
}
